Spring Security Note-15
重构注册逻辑
在之前浏览器的社交账号登录注册操作逻辑时,发现用户是第一次用社交帐号登录时,它会跳转至配置的注册页上,跳转到注册页之前,会将第三方用户信息放到SESSION当中;
跳转到注册页之后,可以访问/social/user
服务,然后将用户信息从SESSION中提出来,并且提供了providerSignInUtils的根据,从SESSION中拿出用户数据来,一旦用户注册(绑定)完成之后,拿到一个唯一的用户标识,providerSignInUtils再把之前的第三方用户信息拿出来,做一个绑定,存到数据库中;
问题
在APP当中,之前的逻辑是想不通的,因为浏览器是基于SESSION的;
APP是一种属于无SESSION的环境,我们需要对注册逻辑进行改造;
解决
基本的操作思路与验证码的重构一致,我们不将信息存到SESSION当中,而是在传输信息时,先将用户信息存到一个外部存储(REDIS)当中,携带一个deviceId;
存放社交信息工具类AppSignUpUtils
1 |
|
SpringSocialConfigurerPostProcessor
SpringSocialConfigurerPostProcessor ,在所有的Bean初始化之前,如果是配置了imoocSocialSecurityConfig,就重行定义注册的处理器;
1 |
|
处理注册处理器AppSecurityController
1 |
|
这样如果在使用社交帐号进行登录时,如果在数据库中没有对应的用户信息,就会引导进行注册,而且不是之前配置的注册页面的逻辑;
此时用户信息已经封装在UserInfo中,并存放在redis中了,在执行注册的请求;
Token处理
基本的Token参数配置
Token的处理都在认证服务器内完成,对ImoocAuthorizationServerConfig
进行配置;
1 |
|
返回的结果当中,最明显的就是expires_in;
如果发送时,不带有scope的参数,则会返回所有的scope类型;
-
通用配置类代替
1 | public class OAuth2ClientProperties { |
1 | public class OAuth2Properties { |
1 |
|
-
配置存储方式TokenStoreConfig
现在的存储方式是存储在内存当中的,当服务重启时,就会清除;
此时我们需要将它存储在独立的容器中,例如数据库或Redis;
1 |
|
1 |
|
-
测试
JWT替换默认令牌
JWT(Json Web Token):是JSON开放的Token标准,与默认的区别在于:
自包含:里面包含有意义的信息。Spring默认的Token是UUID生成的Token,本身无任何意义,本身不包含任何信息,信息是单独保存的。JWT的Token的是包含有意义信息的,如果存放Token的依赖储存器(Redis)奔溃或不可测情况,Token进行解读即可;
密签:为了自包含中的信息不可被随意的修改,并且不包含相关的业务信息,可用指定的密钥进行签名,防止篡改,修改即可知道;
可拓展:所包含的信息可用根据业务需求进行自定义;
-
配置TokenStoreConfig
1 | public class OAuth2Properties { |
1 |
|
修改ImoocAuthorizationServerConfig
1 |
|
返回结果(JWT)
自包含解码结果
-
此时再通过access_token去获取用户信息,发现无返回内容;
实际,我们在用户信息/user/me
中的参数UserDetails,实际我们传入的参数并不是UserDetails,而是一个字符串,所以无法获取到对应的用户信息;
参数修改为Authentication
1 | "/me") ( |
-
自拓展ImoocJwtTokenEnhancer
1 | public class ImoocJwtTokenEnhancer implements TokenEnhancer { |
添加配置TokenStoreConfig
1 |
|
修改认证服务器
1 | false) (required = |
返回结果
再次访问用户信息,实际上不存在我们自拓展的信息,只包含规范内的信息;
如果需要解析自拓展的信息,则需要以下操作;
解析
添加依赖
1 | <dependency> |
1 | "/me") ( |
令牌刷新
令牌无效后,不能反复登录去重新获取令牌,因为用户会用户体验极差;
在返回refresh_token,在无感知的情况下,获取一个新的access_token;